package com.youlai.boot.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.core.security.util.SecurityUtils;
import com.youlai.boot.excel.ReflectUtils;
import com.youlai.boot.excel.Sheet1DTO;
import com.youlai.boot.excel.Sheet2DTO;
import com.youlai.boot.excel.SheetFieldUtil;
import com.youlai.boot.system.converter.SysYouqitouziConverter;
import com.youlai.boot.system.mapper.SysYouqitouziMapper;
import com.youlai.boot.system.model.entity.SysYouqitouzi;
import com.youlai.boot.system.model.form.SysYouqitouziForm;
import com.youlai.boot.system.model.query.SysYouqitouziQuery;
import com.youlai.boot.system.model.vo.*;
import com.youlai.boot.system.service.SysYouqitouziService;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 油气项目服务实现类
 *
 * @author lwb
 * @since 2025-05-29 21:40
 */
@Service
@RequiredArgsConstructor
public class SysYouqitouziServiceImpl extends ServiceImpl<SysYouqitouziMapper, SysYouqitouzi> implements SysYouqitouziService {

    private final SysYouqitouziConverter sysYouqitouziConverter;

    /**
     * 获取油气项目分页列表
     *
     * @param queryParams 查询参数
     * @return {@link IPage<SysYouqitouziVO>} 油气项目分页列表
     */
    @Override
    public IPage<SysYouqitouziVO> getSysYouqitouziPage(SysYouqitouziQuery queryParams) {
        Page<SysYouqitouziVO> pageVO = this.baseMapper.getSysYouqitouziPage(new Page<>(queryParams.getPageNum(), queryParams.getPageSize()), queryParams);
        return pageVO;
    }

    /**
     * 获取油气项目表单数据
     *
     * @param id 油气项目ID
     * @return
     */
    @Override
    public SysYouqitouziForm getSysYouqitouziFormData(Long id) {
        SysYouqitouzi entity = this.getById(id);
        if (Objects.isNull(entity)) {
            throw new RuntimeException("项目概况数据不存在！");
        }
        SysYouqitouziBaseFrom baseFrom = baseMapper.selectBaseByTouziId(id);
        if (Objects.isNull(baseFrom)) {
            throw new RuntimeException("项目数据不存在！");
        }
        SysYouqitouziForm form = sysYouqitouziConverter.toForm(entity);
        BeanUtil.copyProperties(baseFrom, form);
        return form;
    }

    /**
     * 更新油气项目
     *
     * @param id       油气项目ID
     * @param formData 油气项目表单对象
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSysYouqitouzi(Long id, SysYouqitouziForm formData) {
        if (!containsAnyKeyword(formData.getXmmc1())) {
            throw new RuntimeException("项目概况：【项目名称】数据格式错误，应包含【油田，气田，油气田】中的任意一个！");
        }
        SysYouqitouzi youqitouziEntity = this.getById(id);
        if (Objects.isNull(youqitouziEntity)) {
            throw new RuntimeException("项目概况数据不存在！");
        }
        SysYouqitouzi youqitouziBaseEntity = baseMapper.getBaseByTouziId(id);
        if (Objects.isNull(youqitouziBaseEntity)) {
            throw new RuntimeException("项目数据不存在！");
        }

        LambdaQueryWrapper<SysYouqitouzi> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SysYouqitouzi::getXmmc1, formData.getXmmc1());
        lqw.ne(SysYouqitouzi::getId, id);
        lqw.last("limit 1");
        SysYouqitouzi sysYouqitouzi = baseMapper.selectOne(lqw);
        if (Objects.nonNull(sysYouqitouzi)) {
            throw new RuntimeException("项目已录入系统，不要重复录入");
        }

        SysYouqitouzi entity = new SysYouqitouzi();
        BeanUtil.copyProperties(formData, entity);
        entity.setUpdateBy(SecurityUtils.getUserId());
        entity.setUpdateTime(LocalDateTime.now());

        SysYouqitouziBaseFrom baseFrom = new SysYouqitouziBaseFrom();
        BeanUtil.copyProperties(formData, baseFrom);
        SysYouqitouzi baseEntity = sysYouqitouziConverter.toEntity(baseFrom);
        baseEntity.setId(youqitouziBaseEntity.getId());
        baseEntity.setTouziId(id);
        baseEntity.setUpdateBy(SecurityUtils.getUserId());
        baseEntity.setUpdateTime(LocalDateTime.now());
        setBaseValue(entity, baseEntity);

        updateBatchById(Arrays.asList(entity, baseEntity));
        return true;
    }

    /**
     * 删除油气项目
     *
     * @param ids 油气项目ID，多个以英文逗号(,)分割
     * @return
     */
    @Override
    public boolean deleteSysYouqitouzis(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的油气项目数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();
        baseMapper.delBatchByIds(idList);
        return true;
    }

    @Override
    public SysDashboardVO dashboard(SysYouqitouziQuery req) {
        //列出原油采收率最低的3个项目
        List<DashboardWarnVO> yyList = baseMapper.yyList(req);
        if (CollUtil.isEmpty(yyList)) {
            yyList = new ArrayList<>();
        }
        // 列出天然气采收率最低的3个项目
        List<DashboardWarnVO> trqList = baseMapper.trqList(req);
        if (CollUtil.isEmpty(trqList)) {
            trqList = new ArrayList<>();
        }
        //列出米钻井成本最高的3个项目
        List<DashboardWarnVO> mzjList = baseMapper.mzjList(req);
        if (CollUtil.isEmpty(mzjList)) {
            mzjList = new ArrayList<>();
        }
        //高峰产能
        DashboardCountVO gfcnCount = baseMapper.gfcnCount(req);
        List<DashboardWarnVO> gfcnList = new ArrayList<>();
        if (Objects.nonNull(gfcnCount)) {
            for (int i = 1; i <= 5; i++) {
                DashboardWarnVO vo = getVo(i, gfcnCount);
                gfcnList.add(vo);
            }
        }
        //总投资
        DashboardCountTouZiVO ztzCount = baseMapper.ztzCount(req);
        List<DashboardWarnVO> ztzList = new ArrayList<>();
        if (Objects.nonNull(ztzCount)) {
            for (int i = 1; i <= 5; i++) {
                DashboardWarnVO vo = getTouZiVo(i, ztzCount);
                ztzList.add(vo);
            }
        }
        SysDashboardVO dashboardVO = new SysDashboardVO();
        dashboardVO.setYyList(yyList);
        dashboardVO.setTrqList(trqList);
        dashboardVO.setMzjList(mzjList);
        dashboardVO.setGfcnList(gfcnList);
        dashboardVO.setZtzList(ztzList);
        return dashboardVO;
    }

    @NotNull
    private static DashboardWarnVO getVo(int i, DashboardCountVO gfcnCount) {
        DashboardWarnVO vo = new DashboardWarnVO();
        if (i == 1) {
            vo.setName("0<50万吨");
            vo.setValue(gfcnCount.getValue0Range50());
        } else if (i == 2) {
            vo.setName("50-100万吨");
            vo.setValue(gfcnCount.getValue50Range100());
        } else if (i == 3) {
            vo.setName("100-200万吨");
            vo.setValue(gfcnCount.getValue100Range200());
        } else if (i == 4) {
            vo.setName("200-300万吨");
            vo.setValue(gfcnCount.getValue200Range300());
        } else if (i == 5) {
            vo.setName(">300万吨");
            vo.setValue(gfcnCount.getValue300Range());
        }
        return vo;
    }

    @NotNull
    private static DashboardWarnVO getTouZiVo(int i, DashboardCountTouZiVO gfcnCount) {
        DashboardWarnVO vo = new DashboardWarnVO();
        if (i == 1) {
            vo.setName("0<3亿");
            vo.setValue(gfcnCount.getValue0Range3());
        } else if (i == 2) {
            vo.setName("3-10亿");
            vo.setValue(gfcnCount.getValue3Range10());
        } else if (i == 3) {
            vo.setName("10-50亿");
            vo.setValue(gfcnCount.getValue10Range50());
        } else if (i == 4) {
            vo.setName("50-100亿");
            vo.setValue(gfcnCount.getValue50Range100());
        } else if (i == 5) {
            vo.setName(">100亿");
            vo.setValue(gfcnCount.getValue100Range());
        }
        return vo;
    }

    private final static List<String> haiyuList = Arrays.asList("渤海", "东海", "南海东部", "南海西部(海南)", "南海西部(湛江)");
    private final static List<String> typeList = Arrays.asList("油田", "气田", "油气田");
    private final static Integer maxSheet1Size = 12;
    private final static Integer maxSheet2Size = 132;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importExcel(List<Sheet1DTO> sheet1Data, List<Sheet2DTO> sheet2Data) {
        checkValid(sheet1Data, sheet2Data);

        List<Sheet1DTO> projectDataList = new ArrayList<>();
        List<Sheet1DTO> baseProjectDataList = sheet2Data.stream().map(item -> {
            Sheet1DTO projectData = new Sheet1DTO();
            projectData.setIndex(item.getIndex());
            projectData.setValue(item.getValue());
            projectDataList.add(projectData);

            Sheet1DTO baseProjectData = new Sheet1DTO();
            baseProjectData.setIndex(item.getIndex());
            baseProjectData.setValue(item.getBaseValue());
            return baseProjectData;
        }).toList();

        long nextId = IdUtil.getSnowflakeNextId();
        SysYouqitouzi youqitouzi = new SysYouqitouzi();
        youqitouzi.setId(nextId);
        youqitouzi.setTouziId(nextId);
        youqitouzi.setType(1);
        youqitouzi.setTcsj1(youqitouzi.getTcsj10() != null ? youqitouzi.getTcsj10().toString() : "");
        youqitouzi.setCreateBy(SecurityUtils.getUserId());
        youqitouzi.setCreateTime(LocalDateTime.now());
        youqitouzi.setUpdateTime(LocalDateTime.now());
        youqitouzi.setUpdateBy(SecurityUtils.getUserId());
        //项目概况
        for (Sheet1DTO dto : sheet1Data) {
            String index = dto.getIndex();
            String value = dto.getValue();
            // 获取对应字段名
            String fieldName = SheetFieldUtil.SHEET1_MAP.get(index);
            if (fieldName == null) {
                continue; // 忽略未映射的 index
            }
            checkValid(index, value);
            ReflectUtils.setFieldValue(youqitouzi, fieldName, value, index, "项目概况");
        }
        //项目数据-实施情况(后评价)
        buildProjectData(projectDataList, youqitouzi, "项目数据【实施情况(后评价】");

        //项目数据-基本设计批复方案
        SysYouqitouzi youqitouzi1 = new SysYouqitouzi();
        youqitouzi1.setId(IdUtil.getSnowflakeNextId());
        youqitouzi1.setTouziId(nextId);
        youqitouzi1.setType(0);
        setBaseValue(youqitouzi, youqitouzi1);
        youqitouzi1.setCreateBy(SecurityUtils.getUserId());
        youqitouzi1.setCreateTime(LocalDateTime.now());
        youqitouzi1.setUpdateTime(LocalDateTime.now());
        youqitouzi1.setUpdateBy(SecurityUtils.getUserId());
        buildProjectData(baseProjectDataList, youqitouzi1, "项目数据【基本设计批复方案】");

        saveBatch(Arrays.asList(youqitouzi, youqitouzi1));
        return true;
    }

    public void checkValid(String index, String value) {
        if (index.equals("1")) {
            if (StrUtil.isBlank(value)) {
                throw new RuntimeException("项目概况：序号1【项目名称】不能为空！");
            } else {
                if (!containsAnyKeyword(value)) {
                    throw new RuntimeException("项目概况：序号1【项目名称】数据格式错误，应包含【油田，气田，油气田】中的任意一个！");
                }
                LambdaQueryWrapper<SysYouqitouzi> lqw = new LambdaQueryWrapper<>();
                lqw.eq(SysYouqitouzi::getXmmc1, value);
                lqw.last("limit 1");
                SysYouqitouzi sysYouqitouzi = baseMapper.selectOne(lqw);
                if (Objects.nonNull(sysYouqitouzi)) {
                    throw new RuntimeException("项目已录入系统，不要重复录入");
                }
            }
        } else if (index.equals("3") && StrUtil.isNotBlank(value)) {
            boolean contains = haiyuList.contains(value);
            if (!contains) {
                throw new RuntimeException("项目概况：序号3【海域】数据格式错误！应是【渤海，东海，南海东部，南海西部(海南)，南海西部(湛江)】中的任意一个！");
            }
        }
    }

    /**
     * 判断字符串是否包含任意一个关键字
     */
    private static boolean containsAnyKeyword(String text) {
        for (String keyword : typeList) {
            if (text.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    public void checkValid(List<Sheet1DTO> sheet1Data, List<Sheet2DTO> sheet2Data) {
        if (CollUtil.isEmpty(sheet1Data) || CollUtil.isEmpty(sheet2Data)) {
            throw new RuntimeException("请选择要导入的Excel文件！");
        }
        if (sheet1Data.size() != maxSheet1Size || sheet2Data.size() != maxSheet2Size) {
            throw new RuntimeException("请使用系统提供的导入模版进行导入！");
        }
        sheet1Data.stream().filter(item -> StrUtil.isBlank(item.getIndex())).findFirst().ifPresent(item -> {
            throw new RuntimeException("【项目概况】序号不能为空！");
        });
        sheet2Data.stream().filter(item -> StrUtil.isBlank(item.getIndex())).findFirst().ifPresent(item -> {
            throw new RuntimeException("【项目数据】序号不能为空！");
        });
        int sheet1Size = sheet1Data.stream().map(Sheet1DTO::getIndex).collect(Collectors.toSet()).size();
        if (sheet1Size != sheet1Data.size()) {
            throw new RuntimeException("【项目概况】序号不能重复！");
        }
        int sheet2Size = sheet2Data.stream().map(Sheet2DTO::getIndex).collect(Collectors.toSet()).size();
        if (sheet2Size != sheet2Data.size()) {
            throw new RuntimeException("【项目数据】序号不能重复！");
        }
    }

    private void setBaseValue(SysYouqitouzi youqitouzi, SysYouqitouzi youqitouzi1) {
        youqitouzi1.setXmmc1(youqitouzi.getXmmc1());
        youqitouzi1.setFgs2(youqitouzi.getFgs2());
        youqitouzi1.setHy3(youqitouzi.getHy3());
        youqitouzi1.setDlwz4(youqitouzi.getDlwz4());
        youqitouzi1.setSsgzdy5(youqitouzi.getSsgzdy5());
        youqitouzi1.setYqzlx6(youqitouzi.getYqzlx6());
        youqitouzi1.setPjss7(youqitouzi.getPjss7());
        youqitouzi1.setZyxgdw8(youqitouzi.getZyxgdw8());
        youqitouzi1.setJsqzsj9(youqitouzi.getJsqzsj9());
        youqitouzi1.setTcsj10(youqitouzi.getTcsj10());
        youqitouzi1.setHpjfw11(youqitouzi.getHpjfw11());
        youqitouzi1.setHpjsd12(youqitouzi.getHpjsd12());
    }

    private void buildProjectData(List<Sheet1DTO> sheet1DTOList, SysYouqitouzi youqitouzi, String columnName) {
        for (Sheet1DTO dto : sheet1DTOList) {
            String index = dto.getIndex();
            String value = dto.getValue();
            // 获取对应字段名
            String fieldName = SheetFieldUtil.SHEET2_MAP.get(index);
            if (fieldName == null) {
                continue; // 忽略未映射的 index
            }
            ReflectUtils.setFieldValue(youqitouzi, fieldName, value, index, columnName);
        }
    }
}
